/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufba.lasid.virt;

import br.ufba.lasid.v1.jitclouds.mda.datatypes.IMachine;
import br.ufba.lasid.v1.jitclouds.mda.datatypes.virtualization.IHypervisor;
import br.ufba.lasid.v1.jitclouds.mda.datatypes.virtualization.IVirtualMachine;
import br.ufba.lasid.v1.jitclouds.mda.datatypes.virtualization.VirtualMachineList;
import br.ufba.lasid.v1.utils.ValidateIP;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.libvirt.Connect;
import org.libvirt.ConnectAuth;
import org.libvirt.ConnectAuthDefault;
import org.libvirt.Domain;
import org.libvirt.DomainInfo;
import org.libvirt.LibvirtException;

/**
 *
 * @author aliriosa
 */
public class Hypervisor implements IHypervisor {

    private static final String DASH = "------------------------------------------";
    Domain domain = null;
    Connect connection = null;
    ConnectAuth defaultAuth = null;
    String URI = "";

    public static void main(String args[]) throws Exception {

        
        if(args.length < 1){
            System.err.println("You should type args.");
            System.exit(1);
        }
        
        
        Hypervisor Hp = new Hypervisor(args[0]);
        Hp.connect();
        if(args.length > 1){
        if(args[1].equals("list")){
            Hp.listAllVirtualMachine();
        }else if(args[1].equals("create")){
            if(args.length > 2) { 
                Hp.addVirtualMachine(args[2], null);
            }
            else {
                System.out.println("Impossible create a virtual machine without an XML-FILE");
            }
        }else if(args[1].equals("destroy")){
            if(args.length > 2) {
                Hp.delVirtualMachine(args[2]);
            }
            else {
                System.out.println("Choose the ID-MACHINE to destroy and repeat the operation");
            }
        }
        else{
            System.out.println("You need to choose a valid option.");
        }
        System.out.printf("\n\n\n\n\n");
        }
        
        

    }

    public Hypervisor(String URI) {
        this.URI = URI;
        defaultAuth = new ConnectAuthDefault();
    }

    Hypervisor() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public void connect() throws Exception {

        if (URI.equals("")) {
            throw new UnsupportedOperationException("You did not type the URI");
        } else if (URI.equals("localhost")) {

            this.connection = new Connect("xen:///", defaultAuth, 0);
            System.out.println("localhost Encrypted connection successful!");

        } else if (ValidateIP.validate(URI)) {
            this.connection = new Connect("xen+ssh://" + URI + "/", false);
            System.out.println(URI + " Encrypted connection successful!");
        } else {
            throw new UnsupportedOperationException("Ip or URI is not valid");
        }
    }

    public VirtualMachineList getMachines() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void listAllVirtualMachine() throws LibvirtException {
        System.out.println("Capabilities: " + connection.getCapabilities());
        System.out.println("hostname: " + connection.getHostName());
        System.out.println("version: " + connection.getLibVirVersion());
        System.out.println("isSecure: " + connection.isSecure());
        System.out.println("isEncrypted: " + connection.isEncrypted());
        System.out.println("numOfDomains: " + connection.numOfDomains());
        System.out.println("active Domains: " + connection.listDomains().length);

        int[] ids = connection.listDomains();
        System.out.println("Domains informations");
        for (int i : ids) {
            domain = connection.domainLookupByID(i);
            getDomainInfo(domain);
        }
        System.out.println(DASH);
    }

    public void addVirtualMachine(String xmlFile, IVirtualMachine machine) {
        String out = "";


        try {
            File f = new File(xmlFile);
            if (!f.exists()) {
                System.out.println("File xml does not exist!");
                throw new IOException();
            }
            BufferedReader in = new BufferedReader(
                    new FileReader(f));
            String str = "";
            while ((str = in.readLine()) != null) {
                out = out + str;
            }
            in.close();

            // Define a new Domain
            System.out.println("Creating a Domain...");

            domain = connection.domainCreateLinux(out, 0);


            System.out.println("Domain " + domain.getID() + " created!");
        } catch (IOException e) {
            throw new UnsupportedOperationException("Exception on readding file");
        } catch (LibvirtException ex) {
            throw new UnsupportedOperationException("Exception on libvirt");
        } catch (Exception e) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    public void delVirtualMachine(String idMachine) {

        try {
            int idToDelete = Integer.parseInt(idMachine);

            this.domain = this.connection.domainLookupByID(idToDelete);

            if (this.domain != null) {
                System.out.println("Destroying a Domain...");
                this.domain.destroy();
                System.out.println("Domain " + idToDelete
                        + " destroyed!");
            } else {
                System.out.println("Domain didn't find!");
            }
        } catch (LibvirtException ex) {
            System.out.println("Exception libvirt");
        } catch (NumberFormatException e) {
            System.out.println("The ID is not a number");
        }

        throw new UnsupportedOperationException("Not supported yet.");
    }

    public IVirtualMachine getVirtualMachine(String idMachine) {

        try {
            VirtualMachine vm = new VirtualMachine();
            domain = this.connection.domainLookupByID(0);
            DomainInfo dinfo = domain.getInfo();
            vm.getConfiguration().set(VirtualMachine.OSTypeParameter, domain.getOSType());
            vm.getConfiguration().set(VirtualMachine.UUIDParameter, domain.getUUID());
            vm.getConfiguration().set(VirtualMachine.CpusParameter, domain.getMaxVcpus());
            vm.getConfiguration().set(VirtualMachine.IdParameter, domain.getID());
            vm.getConfiguration().set(VirtualMachine.MaxMemoryParameter, domain.getMaxMemory());
            vm.getConfiguration().set(VirtualMachine.NameParameter, domain.getName());
            return vm;
        } catch (Exception e) {
        }
        return null;
    }

    public void execute(String idMachine, String command) {
        try {
            Domain domain = this.connection.domainCreateLinux(command, 0);
        } catch (LibvirtException ex) {
            Logger.getLogger(Hypervisor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static void getDomainInfo(Domain d) throws LibvirtException {
        System.out.println(DASH);
        System.out.println("Domain name = " + d.getName() + " | ID = "
                + d.getID() + " | OSType = " + d.getOSType());
        System.out.println("MaxMemory = " + d.getMaxMemory() + " | "
                + d.getMaxVcpus());
        System.out.println("UUID = " + d.getUUIDString());
        System.out.println("Active? = " + d.isActive());
        System.out.println("Persistent? = " + d.isPersistent());

        DomainInfo df = d.getInfo();
        System.out.println("CPUTime = " + df.cpuTime);
        System.out.println("MaxMem = " + df.maxMem);
        System.out.println("memory = " + df.memory);
        System.out.println("nrVirtCpu = " + df.nrVirtCpu);
        System.out.println("state = " + df.state);
    }

    public IMachine getHost() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setHost(IMachine host) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setID(String ID) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getID() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setDescription(String description) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String getDescription() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

